import React, { useState, useEffect } from 'react';
import generateSignedNetWork from '../../lib/generateSignedNetwork';
import generateSimilarNetwork from '../../lib/generateSimilarNetwork';
import MyCar from '../../components/MyCard';
import { FileAddOutlined, UploadOutlined } from '@ant-design/icons';
import { Card, Button, Pagination, message } from 'antd';
import GenerateNetworkParams from '../../components/GenerateNetworkParams';
import MFEAParamsForm from '../../components/MFEAParamsForm';
import UploadFileForm from '../../components/UploadFileForm';
import { init } from '../../lib/getModularity';
import MFEA from '../../lib/MFEA';
import SOO from '../../lib/SOO';
import { useLocation } from 'react-router-dom';
// eslint-disable-next-line
export default props => {
  const { query: callback } = useLocation();
  const [generateNetworkParamsVisible, setGenerateNetworkParamsVisible] = useState(false);
  const [MFEAParamsVisible, setMFEAParamsVisible] = useState(false);
  const [uploadFileFormVisible, setUploadFileFormVisible] = useState(false);
  const [MFEAResult, setMFEAResult] = useState([]);
  const [title, setTitle] = useState('最终结果');
  const [MFEAParams, setMFEAParams] = useState({
    w: 0.5,
    pop: 50,
    gen: 30,
    selectionProcess: 'elitist',
    rmp: 0.3,
    mutateProbability: 0.3,
    useLocalSearch: true,
    useLocalSearchProbability: 0.05,
    targetFunction: 'H',
  });
  const [graphs, setGraphs] = useState([]);
  let networkParams = {
    networkNum: 6,
    nodeNum: 100,
    communityNum: 10,
    i_p_edgeNum: 300,
    i_n_degeNum: 0,
    o_p_edgeNum: 0,
    o_n_edgeNum: 50,
  };
  useEffect(() => {
    window.localStorage.getItem('tempGraphs') &&
      setGraphs(JSON.parse(window.localStorage.getItem('tempGraphs')));
    window.localStorage.getItem('mfeaResult') &&
      setMFEAResult(JSON.parse(window.localStorage.getItem('mfeaResult')));
  }, [MFEAParams]);
  const getGenerateNetworkParams = val => {
    networkParams = {
      ...networkParams,
      ...val,
    };
    const { networkNum } = networkParams;
    if (networkNum < 2) throw new Error('必须输入多个网络');
    const matrixs = [];
    const edgeDatas = [];
    const { matrix } = generateSignedNetWork(
      networkParams.nodeNum,
      networkParams.communityNum,
      networkParams.i_p_edgeNum,
      networkParams.i_n_degeNum,
      networkParams.o_p_edgeNum,
      networkParams.o_n_edgeNum
    );
    matrixs.push(matrix);
    edgeDatas.push(init(matrix));
    for (let i = 1; i < networkNum; i++) {
      const similarNetwork = generateSimilarNetwork(matrix);
      matrixs.push(similarNetwork);
      edgeDatas.push(init(similarNetwork));
    }
    setMFEAParams({
      ...MFEAParams,
      matrixs,
      edgeDatas,
    });
  };
  const getFileMatrixs = matrixs => {
    let edgeDatas = [];
    for (let i = 0; i < matrixs.length; i++) {
      edgeDatas.push(init(matrixs[i]));
    }
    setMFEAParams({
      ...MFEAParams,
      matrixs,
      edgeDatas,
    });
  };
  const getMFEAParams = async val => {
    const obj = {
      ...MFEAParams,
      ...val,
    };
    const startTime = new Date();
    let res = MFEA(
      obj.matrixs,
      obj.edgeDatas,
      obj.pop,
      obj.gen,
      obj.selectionProcess,
      obj.rmp,
      obj.mutateProbability,
      obj.useLocalSearch,
      obj.useLocalSearchProbability,
      obj.targetFunction,
      obj.w
    );
    const mfeaRunTime = new Date() - startTime;
    window.localStorage.setItem('targetFunction', obj.targetFunction);
    window.localStorage.setItem('mfeaRunTime', mfeaRunTime);
    window.localStorage.setItem('mfeaResult', JSON.stringify(res));
    callback && callback();
    setMFEAParams(obj);
    setMFEAResult(res);
    let arr = [];
    for (let i = 0; i < obj.matrixs.length; i++) {
      arr.push({
        matrix: obj.matrixs[i],
        labels: res[res.length - 1][i].rnvec,
        modularity: res[res.length - 1][i].factorialCost,
        targetFunction: obj.targetFunction,
      });
    }
    window.localStorage.setItem('tempGraphs', JSON.stringify(arr));
    setGraphs(arr);
    runSOO(obj);
  };
  const runSOO = params => {
    const sooRunTimes = [];
    const sooResults = [];
    params.matrixs.forEach((matrix, index) => {
      const startTime = new Date();
      const res = SOO(
        matrix,
        params.edgeDatas[index],
        params.pop,
        params.gen,
        params.selectionProcess,
        params.mutateProbability,
        true,
        params.useLocalSearchProbability,
        params.targetFunction,
        params.w
      );
      sooRunTimes.push(new Date() - startTime);
      sooResults.push(res);
    });
    window.localStorage.setItem('sooRunTimes', JSON.stringify(sooRunTimes));
    window.localStorage.setItem('sooResults', JSON.stringify(sooResults));
  };
  const updateView = page => {
    const graphs = JSON.parse(window.localStorage.getItem('tempGraphs'));
    let arr = [];
    let index;
    if (page === 10) {
      index = MFEAResult.length - 1;
    } else if (page === 1) {
      index = 0;
    } else {
      index = Math.floor((MFEAResult.length - 2) / 8) * (page - 1);
    }

    for (let i = 0; i < graphs.length; i++) {
      arr.push({
        matrix: graphs[i].matrix,
        labels: MFEAResult[index][i].rnvec,
        modularity: MFEAResult[index][i].factorialCost,
        targetFunction: graphs[i].targetFunction,
      });
    }
    setTitle(`第 ${index + 1} 代`);
    setGraphs(arr);
  };
  return (
    <>
      <Card
        title={
          <div>
            <Button
              type="primary"
              size="large"
              shape="round"
              icon={<FileAddOutlined />}
              style={{ marginRight: 20 }}
              onClick={() => {
                setGenerateNetworkParamsVisible(true);
              }}
            >
              生成网络
            </Button>
            <Button
              type="primary"
              size="large"
              shape="round"
              icon={<UploadOutlined />}
              style={{ marginRight: 20 }}
              onClick={() => {
                setUploadFileFormVisible(true);
              }}
            >
              输入网络
            </Button>
          </div>
        }
      >
        <MyCar title={title} graphs={graphs} />
        {
          <div style={{ textAlign: 'center', paddingTop: 10 }}>
            {graphs.length !== 0 && (
              <Pagination
                total={10}
                defaultPageSize="1"
                defaultCurrent="10"
                onChange={(page, pageSize) => {
                  updateView(page);
                }}
              />
            )}
          </div>
        }
      </Card>

      <GenerateNetworkParams
        callback={getGenerateNetworkParams}
        visible={generateNetworkParamsVisible}
        onSuccess={() => {
          setGenerateNetworkParamsVisible(false);
          message.success('已生成网络');
          setMFEAParamsVisible(true);
        }}
        onCancel={() => {
          setGenerateNetworkParamsVisible(false);
        }}
      ></GenerateNetworkParams>
      <MFEAParamsForm
        callback={getMFEAParams}
        visible={MFEAParamsVisible}
        onSuccess={() => {
          message.success('运行成功，正在绘制分类结果');
          setMFEAParamsVisible(false);
        }}
        onCancel={() => {
          setMFEAParamsVisible(false);
        }}
      ></MFEAParamsForm>
      <UploadFileForm
        callback={getFileMatrixs}
        visible={uploadFileFormVisible}
        onSuccess={() => {
          setUploadFileFormVisible(false);
          message.success('已读取文件数据，请设置算法参数');
          setMFEAParamsVisible(true);
        }}
        onCancel={() => {
          setUploadFileFormVisible(false);
        }}
      ></UploadFileForm>
    </>
  );
};
